import html2canvas from 'html2canvas';
import jsPDF from '../../utils/thirdPackage/jspdf';

export default function (
  gap = 16, // 元素间隔(HTML)
  HTMLWidth = 920, // HTML页面宽度(HTML)，对应的高度为1301
  pdfWidth = 595.28, // PDF纸张的宽度(PDF)
  pdfHeight = 841.89, // PDF纸张高度(PDF)
  pdfLeftRightGap = 20, // 在PDF中左右留的边距(PDF)
  pdfTopGap = 20, // 在pdf上面预留的高度
  pdfBottomGap = 26, // 在pdf下面预留的高度
  pageHeader = 36, // 每一页页头的高度(HTML)
) {
  this.gap = gap; // 元素间隔(HTML)
  this.HTMLWidth = HTMLWidth; // HTML页面宽度(HTML)，对应的高度为1301
  this.pdfWidth = pdfWidth; // PDF纸张的宽度(PDF)
  this.pdfHeight = pdfHeight; // PDF纸张高度(PDF)
  this.pdfLeftRightGap = pdfLeftRightGap; // 在PDF中左右留的边距(PDF)
  this.pdfTopGap = pdfTopGap; // 在pdf上面预留的高度
  this.pdfBottomGap = pdfBottomGap; // 在pdf下面预留的高度（后期添加页码）
  this.pageHeader = pageHeader; // 每一页页头的高度(HTML)

  // 生成空白canvas元素
  this.blankImgData = function (height) {
    // 创建空白元素，可添加到PDF中的对象
    const blankCanvas = document.createElement('canvas');
    blankCanvas.width = this.pdfWidth;
    blankCanvas.height = height;
    blankCanvas.style.backgroundColor = 'white';
    var ctx = blankCanvas.getContext('2d');
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, this.pdfWidth, height);
    let blankImgData = blankCanvas.toDataURL('image/jpeg', 1);
    return blankImgData;
  };

  // 创建空白头元素，可添加到PDF中的对象（每页头部空白）
  this.headerBlankImgData = this.blankImgData(this.pdfTopGap);

  // 生成页码元素
  this.pageImgData = function (page) {
    // 创建页码元素，添加到每页末尾
    const pageCanvas = document.createElement('canvas');
    let width = this.HTMLWidth;
    let height = (this.HTMLWidth * this.pdfBottomGap) / (this.pdfWidth - this.pdfLeftRightGap * 2);
    pageCanvas.width = width;
    pageCanvas.height = height;
    var ctx = pageCanvas.getContext('2d');
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, width, height);

    // 画一条线
    ctx.moveTo(0, 0);
    ctx.lineTo(this.HTMLWidth, 0);
    ctx.strokeStyle = '#DDDDDD';
    ctx.stroke();

    // 写上页码
    ctx.fillStyle = '#333333';
    ctx.font = '14px sans-serif';
    ctx.fillText(page > 9 ? page : `0${page}`, this.HTMLWidth - 25, 20);

    let pageImgData = pageCanvas.toDataURL('image/jpeg', 1);
    return pageImgData;
  };

  /**
   * @param id  父节点id
   * @param drawingItemName  导出元素name
   * @param headerImgData    页眉元素
   * @param name  导出文件名称
   * @param callback
   */
  this.savePDF = function (id, drawingItemName, name, callback) {
    setTimeout(() => {
      html2canvas(document.getElementById('performanceAnalysisHeader'), {
        scale: 2,
      }).then((headerCanvas) => {
        this.headerImgData = headerCanvas.toDataURL('image/jpeg', 1);
        html2canvas(document.getElementById(id), {
          scale: 2,
          timeout: 1000,
        }).then(async (canvas) => {
          // 可添加到PDF中的对象 （当前需要转为PDF的全部动态元素）
          const imgData = canvas.toDataURL('image/jpeg', 1);

          const pdfObj = new jsPDF('p', 'pt', 'a4'); // PDF对象
          const pdfInnerWidth = this.pdfWidth - this.pdfLeftRightGap * 2; // PDF内部去掉边距内部实际可使用的宽度
          const headerBlankInPDFH = this.pdfTopGap + ((this.pageHeader + this.gap) * pdfInnerWidth) / this.HTMLWidth; // 头部空白在PDF中高度
          const pdfInnerHeight = this.pdfHeight - (headerBlankInPDFH + this.pdfBottomGap); // PDF内部去掉编辑内部实际可使用的高度
          const headerInPDFH = (this.pageHeader * pdfInnerWidth) / this.HTMLWidth; // header在pdf中的高度
          const gapInPDFH = (this.gap * pdfInnerWidth) / this.HTMLWidth; // 元素之间的空隙在PDF中的高度
          const currentHTMLWidth = canvas.width; // 当前需要转换为PDF的元素的宽度 （HTML宽度）
          const currentHTMLHeight = canvas.height; // 当前需要转换的PDF的元素的高度（HTML的高度）
          const currentPdfHeight = (pdfInnerWidth * currentHTMLHeight) / currentHTMLWidth; // 当前需要转换为PDF的元素在PDF中高度
          const elements = document.getElementsByName(drawingItemName); // 需要导出的元素

          let nextIndex = 0; // 下一页PDF起始的元素序号
          let htmlInPDFHeight = 0; // 已经在PDF上的元素的高度
          let currentPage = 0; // 记录当前正在处理pdf的第几页
          let finish = false; // 记录是否完成分析，可以执行导出了
          while (finish == false) {
            // 刚开始时，累计到pdf的元素的高度是0，如果不是第一页，则添加一页PDF
            if (htmlInPDFHeight != 0) {
              pdfObj.addPage();
              currentPage++;
            }

            let height = 0; // 搜集当前一页元素的累计高度
            let i;
            // 针对每一个元素，逐个遍历，从上一页未处理的第一个元素开始遍历
            for (i = nextIndex; i < elements.length; i++) {
              // 若不是当前页的第一个元素，则累积高度添加间隔
              if (i != nextIndex) {
                height += gapInPDFH;
              }

              // 计算当前元素在pdf中占的高度
              let pdfCurrentItemHeight = (elements[i].clientHeight * pdfInnerWidth) / this.HTMLWidth;
              // 若累计当前元素后，大于了内容区的高度（证明当前元素不能完全放入该页）
              if (height + pdfCurrentItemHeight > pdfInnerHeight) {
                nextIndex = i; // 记录下一轮开始的元素
                break;
              } else {
                // 若空白区域足够放当前元素
                height += pdfCurrentItemHeight;
              }
            }

            /**------ 在换页之前（一次while结尾）添加一页PDF---------- */

            // 叠加元素
            pdfObj.addImage(imgData, 'JPEG', this.pdfLeftRightGap, headerBlankInPDFH - htmlInPDFHeight, pdfInnerWidth, currentPdfHeight);

            // 叠加头部空白
            pdfObj.addImage(this.headerBlankImgData, 'JPEG', this.pdfLeftRightGap, 0, pdfInnerWidth, headerBlankInPDFH);

            // 叠加header
            pdfObj.addImage(this.headerImgData, 'JPEG', this.pdfLeftRightGap, this.pdfTopGap, pdfInnerWidth, headerInPDFH);

            // 叠加尾部空白
            const endBlankImgData = this.blankImgData(pdfInnerHeight - height + this.pdfBottomGap);
            pdfObj.addImage(endBlankImgData, 'JPEG', this.pdfLeftRightGap, headerBlankInPDFH + height, pdfInnerWidth, pdfInnerHeight - height + this.pdfBottomGap);

            // 叠加页码
            if (currentPage !== 0) {
              const pageImgData = this.pageImgData(currentPage);
              pdfObj.addImage(pageImgData, 'JPEG', this.pdfLeftRightGap, this.pdfHeight - this.pdfBottomGap, pdfInnerWidth, this.pdfBottomGap);
            }

            // 记录已经复制到pdf上的元素的pdf高度
            htmlInPDFHeight += height;

            // 最后一个元素，且没有未处理完的表格，则退出循环
            if (i == elements.length) {
              finish = true;
            }
          }

          pdfObj.save(`${name}.pdf`);
          callback('success');
        });
      });
    }, 1000);
  };
}
